package com.icebartech.core.utils;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * 微信支付工具类
 * @author Administrator
 *
 */
public class WeiXinPayUtil {

	/**
	 * 获得微信支付md5签名后的sign值 32位md5
	 * @param apiSecret
	 * @param params 微信支付要求的所有非空参数
	 * @return
	 */
	public static String getSign(String apiSecret, Map<String, String> params){
		StringBuffer prestr = new StringBuffer();
		if(StringUtils.isEmpty(apiSecret)){
			throw new RuntimeException("param [appId] or [apiSecret] can not be null!");
		}
		List<String> keys = new ArrayList<String>(params.keySet());
        Collections.sort(keys);

        for (int i = 0; i < keys.size(); i++) {
            String key = keys.get(i);
            String value = params.get(key);
            if (i == keys.size() - 1) {//拼接时，不包括最后一个&字符
                prestr.append(key + "=" + value);
            } else {
                prestr.append(key + "=" + value + "&");
            }
        }
        //末尾加上apiSecret
        prestr.append("&key=" + apiSecret);
        //进行md5加密
        String md5Sign = MD5.sign(prestr.toString());
        //转换成大写
        // prestr = md5Sign.toUpperCase();
        // return prestr;
		return md5Sign.toUpperCase();
	}
	
	/** 
     * 除去数组中的空值和签名参数
     * @param sArray 签名参数组
     * @return 去掉空值与签名参数后的新签名参数组
     */
    public static Map<String, String> paramFilter(Map<String, String> sArray) {
        Map<String, String> result = new HashMap<String, String>();
        if (sArray == null || sArray.size() <= 0) {
            return result;
        }
		for (Map.Entry<String,String> e : sArray.entrySet()) {
			String value = e.getValue();
			String key = e.getKey();
			if (value == null || value.equals("") || key.equalsIgnoreCase("sign")) {
				continue;
			}
			result.put(key, value);
		}
        // for (String key : sArray.keySet()) {
        //     String value = sArray.get(key);
        //     if (value == null || value.equals("") || key.equalsIgnoreCase("sign")) {
        //         continue;
        //     }
        //     result.put(key, value);
        // }
        return result;
    }
	
	/**
	 * 随机获取32位数字与字母的组合
	 * @return
	 */
	public static String getNonceStr(){
		return RandomStringUtils.randomAlphanumeric(32);
	}
	
	/**
	 * 获取本机ip
	 * @return
	 */
	public static String getMachineIp(){
		String ip = "127.0.0.1";
		try {
			InetAddress address = InetAddress.getLocalHost();
			String hostIp = address.getHostAddress().toString();
			if(StringUtils.isNotEmpty(hostIp)){
				ip = hostIp;
			}
		} catch (UnknownHostException e) {
			
		}
		return ip;
	}
	
	/**
	 * 把微信支付返回的xml转换成map返回
	 * @param xml
	 * @return
	 */
	public static Map<String, String> parseXmlToMap(String xml){
		Map<String, String> rtnMap = null;
		if(StringUtils.isNotEmpty(xml)){
			rtnMap = new HashMap<String, String>();
			DocHelper docHelper = new DocHelper(xml);
			Document document = docHelper.getDoc();
			if(document != null){
				NodeList nodeList = document.getElementsByTagName("xml").item(0).getChildNodes();
				if(nodeList != null){
					for(int i = 0; i < nodeList.getLength(); i++){
						Node node = nodeList.item(i);//这他妈的jdk的xml解析太挫了！！这里不能getFirstChild()
						if(node != null){
							String value = node.getFirstChild().getNodeValue();//到这里才能getFirstChild()，否则拿不到name和value
							rtnMap.put(node.getNodeName(), value);
						}
					}
				}
			}
		}
		return rtnMap;
	}
	
	public static void main(String[] args) {
//		String appId = "wxd930ea5d5a258f4f";
//		String appSecret = "8934e7d15453e97507ef794cf7b0519d";
//		Map<String, String> params = new HashMap<String, String>();
//		params.put("appid", appId);
//		params.put("auth_code", "123456");
//		params.put("body", "test");
//		params.put("device_info", "123");
//		params.put("mch_id", "1900000109");
//		params.put("nonce_str", "960f228109051b9969f76c82bde183ac");
//		params.put("out_trade_no", "1400755861");
//		params.put("spbill_create_ip", "127.0.0.1");
//		params.put("total_fee", "1");
////		
//		String sign = getSign(appSecret, params);
//		params.put("sign", sign);
//		String var = "appid=wxd930ea5d5a258f4f&auth_code=123456&body=test&device_info=123&mch_id=1900000109&nonce_str=960f228109051b9969f76c82bde183ac&out_trade_no=1400755861&spbill_create_ip=127.0.0.1&total_fee=1&key=8934e7d15453e97507ef794cf7b0519d";
//		
//		System.out.println(DigestUtils.md5Hex(var));
//		System.out.println(getNonceStr());
		
//		System.out.println(getMachineIp());
		
//		String xml = "<xml><ToUserName><![CDATA[ohRuwt24C6Nt6FMNXbnQTcYOuZbg]]></ToUserName><FromUserName><![CDATA[gh_e224722c001e]]></FromUserName><CreateTime><![CDATA[1415627731]]></CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[您的消息我们已收到，感谢您的支持~，我们将尽快回复您的消息！]]></Content></xml>";
//		System.out.println(parseXmlToMap(xml));
		
		
		/*
		Map<String, String> paramMap = new HashMap<String, String>();
		paramMap.put("appid", "wxfb157a4eacfc5310");
		paramMap.put("mch_id", "10028578");
		paramMap.put("nonce_str", WeiXinPayUtil.getNonceStr());
		paramMap.put("body", "测试商品等");
		paramMap.put("out_trade_no", String.valueOf(101));
		paramMap.put("total_fee", String.valueOf((int)(0.01 * 100)));
		paramMap.put("spbill_create_ip", "127.0.0.1");
		String nowTime = DateTimeUtility.timeofnow();
		String twoDaysLater = DateTimeUtility.timeofnowFromStr(DateTimeUtility.addTime(nowTime, "D", 2));
		paramMap.put("time_start", DateTimeUtility.timeofWeiXinPay(nowTime));
		paramMap.put("time_expire", DateTimeUtility.timeofWeiXinPay(twoDaysLater));
		paramMap.put("notify_url", "http://m.weipaidaojia.com/innofarm/weiXinPayCallback");
		paramMap.put("trade_type", WeiPaiConstants.WEIXIN_PAY_TRADE_TYPE_JSAPI);
		paramMap.put("openid", "ohRuwt7ixpuVlwGElboviSmlau9s");
		
		String sign = WeiXinPayUtil.getSign("VHcXRd4FbxgKyXbfD6ovwwJRyIDJ8ZwR", paramMap);
		paramMap.put("sign", sign);
		String postXml = WeiXinMessageUtil.getWeiXinPayXml(paramMap);
		System.out.println(postXml);
		String rtnXml = HttpConnectUtil.doBodyPostXml(WeiXinConstant.WEIXIN_PAY_UNIFIEDORDER, null, postXml);
		System.out.println(rtnXml);
		*/
		
		
		String rtnXml = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg><appid><![CDATA[wxfb157a4eacfc5310]]></appid><mch_id><![CDATA[10028578]]></mch_id><nonce_str><![CDATA[WVcliyzzwKPmqC2A]]></nonce_str><sign><![CDATA[A7C651007EE33F735236F456932BD6F9]]></sign><result_code><![CDATA[SUCCESS]]></result_code><prepay_id><![CDATA[wx20141112000716b5b839db8c0665385253]]></prepay_id><trade_type><![CDATA[JSAPI]]></trade_type></xml>";
		/*
		
		//把返回的xml解析成map
		Map<String, String> rtnMap = WeiXinPayUtil.parseXmlToMap(rtnXml);
		String returnCode = rtnMap.get("return_code");
		//微信返回的签名
		String weiXinSign = rtnMap.get("sign");
		//校验签名
		Map<String, String> filterMap = WeiXinPayUtil.paramFilter(rtnMap);
		//自己加密后的sign
		String ownSign = WeiXinPayUtil.getSign("VHcXRd4FbxgKyXbfD6ovwwJRyIDJ8ZwR", filterMap);
		
		//比较签名是否一致
		if(weiXinSign.equals(ownSign)){
			System.out.println("returnCode:" + returnCode + ", weiXinSign:" + weiXinSign + ", ownSign:" + ownSign);
		}else{
			System.out.println("签名不一致！");
		}
		*/
//		String rtnPostXml = HttpConnectUtil.doBodyPostXml("http://127.0.0.1:8080/innofarm/weiXinPayCallback/13", null, rtnXml);
//		System.out.println(rtnPostXml);
		
//		String nowTime = DateTimeUtility.timeofnow();
//		String twoDaysLater = DateTimeUtility.addTime(nowTime, "D", 2);
//		System.out.println(DateTimeUtility.timeofWeiXinPay(nowTime));
//		System.out.println(DateTimeUtility.timeofWeiXinPay(twoDaysLater));
		System.out.println(getNonceStr());
	}
	
}
